package com.metadata_system.api.inspect;

import org.aspectj.lang.reflect.MethodSignature;
import com.metadata_system.api.annotations.CheckTokenUser;
import com.metadata_system.common.db.mapper.UserMapper;
import com.metadata_system.common.dto.JwtToken;
import com.metadata_system.common.http.request_dto.LoginUserRequest;
import com.metadata_system.common.service.TokenValidate;
import com.metadata_system.common.utils.JwtUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
/**
 * 登录用户处理
 * @author safi
 * @date 2019年10月10日16:55:49
 */
public class TokenUserAspect {
    @Autowired(required = false)
    JwtUtil jwtUtil;
    @Autowired
    TokenValidate tokenValidate;
    @Autowired
    LoginUserRequest loginUserRequest;
    @Autowired(required = false)
    UserMapper userMapper;

    @SneakyThrows
    @Around("@annotation(com.metadata_system.api.annotations.CheckTokenUser)")
    public Object checkLogin(ProceedingJoinPoint point) {
//        try{
        // 1.获取 request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        if (request == null) {
            log.info("request 获取失败");
            throw new SecurityException("request 获取失败");
        }

        // 2.校验 token
        if (this.tokenValidate == null) {
            log.info("this.tokenValidate 获取失败");
        }
        JwtToken jwtToken = this.tokenValidate.checkToken(request);
        if (jwtToken == null) {
            log.info("用户token 获取失败");
            throw new SecurityException("token 失效");
        }

        // 角色检查
        MethodSignature signature = (MethodSignature) point.getSignature();
        CheckTokenUser checkTokenUser=signature.getMethod().getAnnotation(CheckTokenUser.class);
        if (checkTokenUser.role()!=null && checkTokenUser.role().length>0){
            String role = userMapper.getRoleById(jwtToken.decodeID());
            if (!Arrays.asList(checkTokenUser.role()).contains(role)){
                throw new SecurityException("当前角色 不允许访问");
            }
        }



        // 解密用户uid
        // jwtToken.setId(jwtToken.decodeID());

        // 3.存储-登录用户信息
        loginUserRequest.setTokenUser(jwtToken);
        return point.proceed();
    }
}
